package com.qinyunkj.searchchatserver.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qinyunkj.searchchatserver.mapper.ArticleMapper;
import com.qinyunkj.searchchatserver.mapper.ArticleQAMapper;
import com.qinyunkj.searchchatserver.model.dto.ArticleAnalysis;
import com.qinyunkj.searchchatserver.model.entity.Article;
import com.qinyunkj.searchchatserver.model.entity.ArticleQA;
import com.qinyunkj.searchchatserver.model.vo.ArticleStatistics;
import com.qinyunkj.searchchatserver.service.ArticleService;
import com.qinyunkj.searchchatserver.service.CrawlerService;
import com.qinyunkj.searchchatserver.service.ChatGPTService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {

    private final CrawlerService crawlerService;
    private final ArticleQAMapper articleQAMapper;
    private final ChatGPTService chatGPTService;

    @Override
    @Cacheable(value = "articles", key = "'page:' + #pageNum + ':' + #pageSize + ':' + #keyword")
    public Page<Article> pageArticles(Integer pageNum, Integer pageSize, String keyword) {
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(keyword)) {
            wrapper.like(Article::getTitle, keyword)
                  .or()
                  .like(Article::getContent, keyword);
        }
        wrapper.orderByDesc(Article::getCreateTime);
        return page(new Page<>(pageNum, pageSize), wrapper);
    }

    @Override
    @Cacheable(value = "articles", key = "'category:' + #category + ':page:' + #pageNum + ':' + #pageSize")
    public Page<Article> getArticlesByCategory(String category, Integer pageNum, Integer pageSize) {
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Article::getCategory, category)
              .orderByDesc(Article::getCreateTime);
        return page(new Page<>(pageNum, pageSize), wrapper);
    }

    @Override
    @Cacheable(value = "categories")
    public List<String> getAllCategories() {
        // 获取所有非空的分类
        return baseMapper.selectList(null)
                .stream()
                .map(Article::getCategory)
                .filter(StringUtils::isNotBlank)
                .distinct()
                .collect(Collectors.toList());
    }

    @Override
    @Cacheable(value = "articles", key = "'hot:' + #limit")
    public List<Article> getHotArticles(int limit) {
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(Article::getCreateTime)
              .last("LIMIT " + limit);
        return list(wrapper);
    }

    @Override
    @Cacheable(value = "articles", key = "'tag:' + #tag + ':page:' + #pageNum + ':' + #pageSize")
    public Page<Article> getArticlesByTag(String tag, Integer pageNum, Integer pageSize) {
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(Article::getTags, tag)
              .orderByDesc(Article::getCreateTime);
        return page(new Page<>(pageNum, pageSize), wrapper);
    }

    @Override
    @Cacheable(value = "tags")
    public List<String> getAllTags() {
        // 获取所有非空的标签并去重
        return baseMapper.selectList(null)
                .stream()
                .map(Article::getTags)
                .filter(StringUtils::isNotBlank)
                .flatMap(tags -> Arrays.stream(tags.split(",")))
                .filter(StringUtils::isNotBlank)
                .distinct()
                .collect(Collectors.toList());
    }

    @Override
    public void crawl(String url) {
        crawlerService.crawl(url);
    }

    @Override
    @Cacheable(value = "statistics", key = "'all'")
    public ArticleStatistics getStatistics() {
        // 获取文章总数
        Long totalArticles = count();

        // 获取分类总数
        Long totalCategories = baseMapper.selectList(null)
                .stream()
                .map(Article::getCategory)
                .filter(StringUtils::isNotBlank)  // 过滤空分类
                .distinct()
                .count();

        // 获取标签总数
        Long totalTags = baseMapper.selectList(null)
                .stream()
                .map(Article::getTags)
                .filter(StringUtils::isNotBlank)  // 过滤空标签
                .flatMap(tags -> Arrays.stream(tags.split(",")))
                .filter(StringUtils::isNotBlank)  // 过滤空字符串
                .distinct()
                .count();

        // 获取最常用的分类
        String mostUsedCategory = baseMapper.selectList(null)
                .stream()
                .map(Article::getCategory)
                .filter(StringUtils::isNotBlank)  // 过滤空分类
                .collect(Collectors.groupingBy(category -> category, Collectors.counting()))
                .entrySet()
                .stream()
                .max(Map.Entry.comparingByValue())
                .map(Map.Entry::getKey)
                .orElse("");

        return new ArticleStatistics(totalArticles, totalCategories, totalTags, mostUsedCategory);
    }

    @Override
    public Page<Article> getArticleList(Integer pageNum, Integer pageSize, String keyword, String category, List<String> tags) {
        Page<Article> page = new Page<>(pageNum, pageSize);

        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<Article>()
            .like(StringUtils.isNotBlank(keyword), Article::getTitle, keyword)
            .eq(StringUtils.isNotBlank(category), Article::getCategory, category)
            .orderByDesc(Article::getCreateTime);

        if (CollectionUtils.isNotEmpty(tags)) {
            wrapper.and(w -> {
                for (String tag : tags) {
                    w.or().like(Article::getTags, tag);
                }
            });
        }

        return this.page(page, wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void analyzeArticle(Long articleId) {
        Article article = baseMapper.selectById(articleId);
        if (article == null) {
            throw new RuntimeException("文章不存在");
        }

        // 调用ChatGPT分析文章
        ArticleAnalysis analysis = chatGPTService.analyzeArticle(
            article.getTitle(), article.getContent());

        // 更新文章分类和标签
        article.setCategory(analysis.getCategory());
        article.setTags(analysis.getTags());
        baseMapper.updateById(article);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<ArticleQA> generateArticleQA(Long articleId) {
        Article article = baseMapper.selectById(articleId);
        if (article == null) {
            throw new RuntimeException("文章不存在");
        }

        // 生成问答对
        List<ArticleQA> qaList = chatGPTService.generateQA(
            article.getTitle(), article.getContent(), 3);

        // 设置文章ID并保存
        qaList.forEach(qa -> {
            qa.setArticleId(articleId);
            articleQAMapper.insert(qa);
        });

        return qaList;
    }

    @Override
    public List<ArticleQA> getArticleQAList(Long articleId) {
        return articleQAMapper.selectList(
            new LambdaQueryWrapper<ArticleQA>()
                .eq(ArticleQA::getArticleId, articleId)
                .orderByDesc(ArticleQA::getCreateTime)
        );
    }
}
